#include "Core.h"

#include <QDebug>

#include <QTimer>
#include <QDataStream>

#include <QScriptEngine>

#include <string.h>

#include "core/Utils.h"
#include "com/QueueMananger.h"
#include "item/Aircraft.h"

using namespace br::org::core;
using namespace br::org::item;

Core* Core::instance = 0;

Core* Core::get()
{
    if ( !instance )
    {
        instance = new Core();
    }
    return instance;
}

 Core::Core() : QObject( 0 )
{
    view = ViewPtr( new View );

    configureLoop();
}

 Core::~Core()
 {
     if ( socketClient )
     {
         delete socketClient;
     }
     if ( socketServer )
     {
         delete socketServer;
     }
     if ( timer )
     {
         delete timer;
     }
     view.clear();
 }

void Core::configureLoop()
{
    timer = new QTimer;
    timer->setSingleShot( false );
    QObject::connect( timer, SIGNAL( timeout() ), view->scene(), SLOT( advance() ) );        
    timer->start( 1000 / 33 );
}

void Core::startCom( QHostAddress hostServer , qint16 portServer, QHostAddress hostClient , qint16 portClient )
{    
    socketServer = new SocketServer( hostServer, portServer);
    socketClient = new SocketClient( hostClient, portClient );

    QObject::connect( timer, SIGNAL( timeout() ), this, SLOT( receive() ) );
    QObject::connect( timer, SIGNAL( timeout() ), socketClient, SLOT( send() ) );
}

void Core::receive()
{
    while( true )
    {
        QByteArray message = QueueMananger::get()->popResponse();

        QDataStream stream( message );
        stream.setVersion( QDataStream::Qt_4_0 );
        QChar type;
        qint32 id;
        stream >> type >> id;

        if ( !message.isEmpty() )
        {                       
            foreach( QGraphicsItem* item, view->items( view->rect() ) )
            {
                Item* selectedItem = dynamic_cast< Item* >( item );
                if ( selectedItem && id == selectedItem->getId() && type == selectedItem->getType() )
                {
                    selectedItem->deserialize( message );
                }
            }
        }
        else
        {
            break;
        }
    }
}

void Core::add( Item* item )
{    
    view->add( item );
}

void Core::showView()
{
    view->show();
}
